Webpack 5μ JavaScript λͺ¨λ νλλ μ΄μ μΌλ‘ λ§μ΄ν¬λ‘ νλ‘ νΈμλμ κ°λ ₯ν κΈ°λ₯μ νμ©νμΈμ. νμ₯ κ°λ₯νκ³ μ μ§λ³΄μ μ©μ΄νλ©° λ 립μ μΈ μΉ μ ν리μΌμ΄μ κ΅¬μΆ λ°©λ²μ λ°°μ보μΈμ.
Webpack 5λ₯Ό μ΄μ©ν JavaScript λͺ¨λ νλλ μ΄μ : λ§μ΄ν¬λ‘ νλ‘ νΈμλλ₯Ό μν μ’ ν© κ°μ΄λ
λμμμ΄ μ§ννλ μΉ κ°λ° νκ²½μμ ν¬κ³ 볡μ‘ν μ ν리μΌμ΄μ μ ꡬμΆνλ κ²μ μ΄λ €μ΄ κ³Όμ μΌ μ μμ΅λλ€. κΈ°μ‘΄μ λͺ¨λ리μ μν€ν μ²λ μ’ μ’ κ°λ° μκ° μ¦κ°, λ°°ν¬ λ³λͺ© νμ, μ½λ νμ§ μ μ§μ μ΄λ €μμΌλ‘ μ΄μ΄μ§λλ€. λ§μ΄ν¬λ‘ νλ‘ νΈμλλ μ΄λ¬ν λ¬Έμ λ€μ ν΄κ²°νκΈ° μν κ°λ ₯ν μν€ν μ² ν¨ν΄μΌλ‘ λ±μ₯νμΌλ©°, νλ€μ΄ λ ν° μΉ μ ν리μΌμ΄μ μ λ 립μ μΈ λΆλΆλ€μ ꡬμΆνκ³ λ°°ν¬ν μ μκ² ν΄μ€λλ€. λ§μ΄ν¬λ‘ νλ‘ νΈμλλ₯Ό ꡬννκΈ° μν κ°μ₯ μ λ§ν κΈ°μ μ€ νλλ Webpack 5μμ λμ λ JavaScript λͺ¨λ νλλ μ΄μ (JavaScript Module Federation)μ λλ€.
λ§μ΄ν¬λ‘ νλ‘ νΈμλλ 무μμΈκ°?
λ§μ΄ν¬λ‘ νλ‘ νΈμλλ νλ‘ νΈμλ μ±μ λ μκ³ λ 립μ μΈ λ¨μλ‘ λΆν΄νλ μν€ν μ² μ€νμΌλ‘, κ° λ¨μλ μλ‘ λ€λ₯Έ νμ μν΄ μμ¨μ μΌλ‘ κ°λ°, ν μ€νΈ λ° λ°°ν¬λ μ μμ΅λλ€. κ° λ§μ΄ν¬λ‘ νλ‘ νΈμλλ νΉμ λΉμ¦λμ€ λλ©μΈμ΄λ κΈ°λ₯μ λ΄λΉνλ©°, λ°νμμ ν¨κ» ꡬμ±λμ΄ μμ ν μ¬μ©μ μΈν°νμ΄μ€λ₯Ό νμ±ν©λλ€.
νλμ κ±°λν κ°λ°ν λμ νΉμ μμμ μ§μ€νλ μ¬λ¬ κ°μ μκ·λͺ¨ νμ΄ μλ νμ¬μ κ°λ€κ³ μκ°νλ©΄ λ©λλ€. κ° νμ λ 립μ μΌλ‘ μμ ν μ μμ΄ κ°λ° μ£ΌκΈ°κ° λΉ¨λΌμ§κ³ μ μ§λ³΄μκ° μ¬μμ§λλ€. μλ§μ‘΄κ³Ό κ°μ λκ·λͺ¨ μ μμκ±°λ νλ«νΌμ μκ°ν΄λ³΄μΈμ. μ¬λ¬ νμ΄ μ ν μΉ΄νλ‘κ·Έ, μΌν μΉ΄νΈ, κ²°μ νλ‘μΈμ€, μ¬μ©μ κ³μ κ΄λ¦¬λ₯Ό κ°κ° κ΄λ¦¬ν μ μμ΅λλ€. μ΄ λͺ¨λ κ²μ΄ λ 립μ μΈ λ§μ΄ν¬λ‘ νλ‘ νΈμλκ° λ μ μμ΅λλ€.
λ§μ΄ν¬λ‘ νλ‘ νΈμλμ μ₯μ :
- λ 립μ μΈ λ°°ν¬: νλ€μ μ ν리μΌμ΄μ μ λ€λ₯Έ λΆλΆμ μν₯μ μ£Όμ§ μκ³ λ§μ΄ν¬λ‘ νλ‘ νΈμλλ₯Ό λ 립μ μΌλ‘ λ°°ν¬ν μ μμ΅λλ€. μ΄λ λ°°ν¬ μνμ μ€μ΄κ³ λ λΉ λ₯Έ λ¦΄λ¦¬μ€ μ£ΌκΈ°λ₯Ό κ°λ₯νκ² ν©λλ€.
- κΈ°μ λΉμ’ μμ±: μλ‘ λ€λ₯Έ λ§μ΄ν¬λ‘ νλ‘ νΈμλλ λ€λ₯Έ κΈ°μ μ΄λ νλ μμν¬(μ: React, Angular, Vue.js)λ₯Ό μ¬μ©νμ¬ κ΅¬μΆλ μ μμ΅λλ€. μ΄λ₯Ό ν΅ν΄ νμ νΉμ μꡬμ κ°μ₯ μ ν©ν κΈ°μ μ μ ννκ³ μ 체 μ ν리μΌμ΄μ μ λ€μ μμ±ν νμ μμ΄ μ μ§μ μΌλ‘ μλ‘μ΄ κΈ°μ μ μ±νν μ μμ΅λλ€. ν νμ μ ν μΉ΄νλ‘κ·Έμ Reactλ₯Ό, λ€λ₯Έ νμ λ§μΌν λλ© νμ΄μ§μ Vue.jsλ₯Ό, μΈ λ²μ§Έ νμ κ²°μ νλ‘μΈμ€μ Angularλ₯Ό μ¬μ©νλ κ²μ μμν΄λ³΄μΈμ.
- ν μμ¨μ± ν₯μ: νμ μμ μ λ§μ΄ν¬λ‘ νλ‘ νΈμλμ λν μμ ν μμ κΆμ κ°μ§λ―λ‘ μμ¨μ±μ΄ μ¦κ°νκ³ μμ¬ κ²°μ μ΄ λΉ¨λΌμ§λ©° κ°λ°μ μμ°μ±μ΄ ν₯μλ©λλ€.
- νμ₯μ± μ¦κ°: λ§μ΄ν¬λ‘ νλ‘ νΈμλλ₯Ό μ¬μ©νλ©΄ κ°λ³ λ§μ΄ν¬λ‘ νλ‘ νΈμλλ₯Ό λ€λ₯Έ μλ²μ λ°°ν¬νμ¬ μ ν리μΌμ΄μ μ μνμ μΌλ‘ νμ₯ν μ μμ΅λλ€.
- μ½λ μ¬μ¬μ©μ±: 곡μ μ»΄ν¬λνΈμ λΌμ΄λΈλ¬λ¦¬λ₯Ό λ§μ΄ν¬λ‘ νλ‘ νΈμλ κ°μ μ½κ² 곡μ ν μ μμ΅λλ€.
- μ©μ΄ν μ μ§λ³΄μ: λ μμ μ½λλ² μ΄μ€λ μΌλ°μ μΌλ‘ μ΄ν΄, μ μ§λ³΄μ λ° λλ²κΉ νκΈ°κ° λ μ½μ΅λλ€.
λ§μ΄ν¬λ‘ νλ‘ νΈμλμ μ΄λ €μ:
- 볡μ‘μ± μ¦κ°: μ¬λ¬ λ§μ΄ν¬λ‘ νλ‘ νΈμλλ₯Ό κ΄λ¦¬νλ κ²μ μ 체 μν€ν μ²μ 볡μ‘μ±μ λν μ μμΌλ©°, νΉν ν΅μ , μν κ΄λ¦¬ λ° λ°°ν¬ μΈ‘λ©΄μμ κ·Έλ μ΅λλ€.
- μ±λ₯ μ€λ²ν€λ: μ¬λ¬ λ§μ΄ν¬λ‘ νλ‘ νΈμλλ₯Ό λ‘λνλ κ²μ μ±λ₯ μ€λ²ν€λλ₯Ό μ λ°ν μ μμΌλ©°, νΉν μ λλ‘ μ΅μ νλμ§ μμ κ²½μ° λμ± κ·Έλ μ΅λλ€.
- κ³΅ν΅ κ΄μ¬μ¬(Cross-Cutting Concerns): μΈμ¦, κΆν λΆμ¬, ν λ§ μ€μ κ³Ό κ°μ κ³΅ν΅ κ΄μ¬μ¬λ₯Ό λ§μ΄ν¬λ‘ νλ‘ νΈμλ μν€ν μ²μμ μ²λ¦¬νλ κ²μ μ΄λ €μΈ μ μμ΅λλ€.
- μ΄μ μ€λ²ν€λ: μ¬λ¬ λ§μ΄ν¬λ‘ νλ‘ νΈμλμ λ°°ν¬ λ° λͺ¨λν°λ§μ κ΄λ¦¬νκΈ° μν΄ μ±μν DevOps κ΄νκ³Ό μΈνλΌκ° νμν©λλ€.
JavaScript λͺ¨λ νλλ μ΄μ μ΄λ 무μμΈκ°?
JavaScript λͺ¨λ νλλ μ΄μ μ Webpack 5μ κΈ°λ₯μΌλ‘, λ³λλ‘ μ»΄νμΌλ JavaScript μ ν리μΌμ΄μ κ°μ λ°νμμ μ½λλ₯Ό 곡μ ν μ μκ² ν΄μ€λλ€. μ΄λ₯Ό ν΅ν΄ μ ν리μΌμ΄μ μ μΌλΆλ₯Ό λ€λ₯Έ μ ν리μΌμ΄μ μμ μλΉν μ μλ "λͺ¨λ"λ‘ λ ΈμΆν μ μμΌλ©°, npmκ³Ό κ°μ μ€μ μ μ₯μμ κ²μν νμκ° μμ΅λλ€.
λͺ¨λ νλλ μ΄μ μ μ ν리μΌμ΄μ μ μ°ν© μνκ³λ₯Ό λ§λλ λ°©λ²μΌλ‘ μκ°ν μ μμ΅λλ€. κ° μ ν리μΌμ΄μ μ μ체 κΈ°λ₯μ μ 곡νκ³ λ€λ₯Έ μ ν리μΌμ΄μ μ κΈ°λ₯μ μλΉν μ μμ΅λλ€. μ΄λ λΉλ μμ μ μ’ μμ±μ μ κ±°νκ³ μ§μ μΌλ‘ λ 립μ μΈ λ°°ν¬λ₯Ό κ°λ₯νκ² ν©λλ€.
μλ₯Ό λ€μ΄, λμμΈ μμ€ν νμ UI μ»΄ν¬λνΈλ₯Ό λͺ¨λλ‘ λ ΈμΆν μ μμΌλ©°, λ€λ₯Έ μ ν리μΌμ΄μ νμ npm ν¨ν€μ§λ‘ μ€μΉν νμ μμ΄ λμμΈ μμ€ν μ ν리μΌμ΄μ μμ μ§μ μ΄λ¬ν μ»΄ν¬λνΈλ₯Ό μλΉν μ μμ΅λλ€. λμμΈ μμ€ν νμ΄ μ»΄ν¬λνΈλ₯Ό μ λ°μ΄νΈνλ©΄ λ³κ²½ μ¬νμ΄ λͺ¨λ μλΉ μ ν리μΌμ΄μ μ μλμΌλ‘ λ°μλ©λλ€.
λͺ¨λ νλλ μ΄μ μ ν΅μ¬ κ°λ :
- νΈμ€νΈ(Host): μ격 λͺ¨λμ μλΉνλ μ£Ό μ ν리μΌμ΄μ μ λλ€.
- μ격(Remote): λ€λ₯Έ μ ν리μΌμ΄μ μμ μλΉν μ μλλ‘ λͺ¨λμ λ ΈμΆνλ μ ν리μΌμ΄μ μ λλ€.
- 곡μ λͺ¨λ(Shared Modules): νΈμ€νΈμ μ격 μ ν리μΌμ΄μ κ°μ 곡μ λλ λͺ¨λμ λλ€(μ: React, Lodash). λͺ¨λ νλλ μ΄μ μ κ° λͺ¨λμ λ¨μΌ λ²μ λ§ λ‘λλλλ‘ κ³΅μ λͺ¨λμ λ²μ κ΄λ¦¬ λ° μ€λ³΅ μ κ±°λ₯Ό μλμΌλ‘ μ²λ¦¬ν μ μμ΅λλ€.
- λ ΈμΆλ λͺ¨λ(Exposed Modules): λ€λ₯Έ μ ν리μΌμ΄μ μμ μλΉν μ μλλ‘ μ 곡λλ μ격 μ ν리μΌμ΄μ μ νΉμ λͺ¨λμ λλ€.
- RemoteEntry.js: Webpackμ μν΄ μμ±λλ νμΌλ‘, μ격 μ ν리μΌμ΄μ μ λ ΈμΆλ λͺ¨λμ λν λ©νλ°μ΄ν°λ₯Ό ν¬ν¨ν©λλ€. νΈμ€νΈ μ ν리μΌμ΄μ μ μ΄ νμΌμ μ¬μ©νμ¬ μ격 λͺ¨λμ λ°κ²¬νκ³ λ‘λν©λλ€.
Webpack 5λ‘ λͺ¨λ νλλ μ΄μ μ€μ νκΈ°: μ€μ© κ°μ΄λ
Webpack 5λ‘ λͺ¨λ νλλ μ΄μ μ μ€μ νλ μ€μ μμ λ₯Ό μ΄ν΄λ³΄κ² μ΅λλ€. νΈμ€νΈ(Host) μ ν리μΌμ΄μ κ³Ό μ격(Remote) μ ν리μΌμ΄μ μ΄λΌλ λ κ°μ κ°λ¨ν μ ν리μΌμ΄μ μ λ§λ€ κ²μ λλ€. μ격 μ ν리μΌμ΄μ μ μ»΄ν¬λνΈλ₯Ό λ ΈμΆνκ³ , νΈμ€νΈ μ ν리μΌμ΄μ μ μ΄λ₯Ό μλΉν©λλ€.
1. νλ‘μ νΈ μ€μ
μ ν리μΌμ΄μ μ μν΄ `host`μ `remote`λΌλ λ κ°μ λ³λ λλ ν°λ¦¬λ₯Ό λ§λλλ€.
```bash mkdir host remote cd host npm init -y npm install webpack webpack-cli webpack-dev-server html-webpack-plugin --save-dev npm install react react-dom cd ../remote npm init -y npm install webpack webpack-cli webpack-dev-server html-webpack-plugin --save-dev npm install react react-dom ```2. μ격 μ ν리μΌμ΄μ ꡬμ±
`remote` λλ ν°λ¦¬μ λ€μ νμΌλ€μ μμ±ν©λλ€:
- `src/index.js`: μ ν리μΌμ΄μ μ μ§μ μ μ λλ€.
- `src/RemoteComponent.jsx`: λ ΈμΆλ μ»΄ν¬λνΈμ λλ€.
- `webpack.config.js`: Webpack κ΅¬μ± νμΌμ λλ€.
src/index.js:
```javascript import React from 'react'; import ReactDOM from 'react-dom/client'; import RemoteComponent from './RemoteComponent'; const App = () => (Remote Application
src/RemoteComponent.jsx:
```javascript import React from 'react'; const RemoteComponent = () => (μ΄κ²μ μ격 μ»΄ν¬λνΈμ λλ€!
μ격 μ ν리μΌμ΄μ μμ λ λλ§λμμ΅λλ€.
webpack.config.js:
```javascript const HtmlWebpackPlugin = require('html-webpack-plugin'); const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin'); const path = require('path'); module.exports = { entry: './src/index', mode: 'development', devServer: { port: 3001, static: { directory: path.join(__dirname, 'dist'), }, }, output: { publicPath: 'auto', }, module: { rules: [ { test: /\.(js|jsx)$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-react', '@babel/preset-env'], }, }, }, ], }, plugins: [ new ModuleFederationPlugin({ name: 'remote', filename: 'remoteEntry.js', exposes: { './RemoteComponent': './src/RemoteComponent', }, shared: { react: { singleton: true, eager: true }, 'react-dom': { singleton: true, eager: true }, }, }), new HtmlWebpackPlugin({ template: './public/index.html', }), ], resolve: { extensions: ['.js', '.jsx'], }, }; ```κΈ°λ³Έμ μΈ HTML ꡬ쑰λ₯Ό κ°μ§ `public/index.html`μ μμ±ν©λλ€. μ€μν κ²μ `
`μ λλ€.3. νΈμ€νΈ μ ν리μΌμ΄μ ꡬμ±
`host` λλ ν°λ¦¬μ λ€μ νμΌλ€μ μμ±ν©λλ€:
- `src/index.js`: μ ν리μΌμ΄μ μ μ§μ μ μ λλ€.
- `webpack.config.js`: Webpack κ΅¬μ± νμΌμ λλ€.
src/index.js:
```javascript import React, { Suspense } from 'react'; import ReactDOM from 'react-dom/client'; const RemoteComponent = React.lazy(() => import('remote/RemoteComponent')); const App = () => (Host Application
webpack.config.js:
```javascript const HtmlWebpackPlugin = require('html-webpack-plugin'); const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin'); const path = require('path'); module.exports = { entry: './src/index', mode: 'development', devServer: { port: 3000, static: { directory: path.join(__dirname, 'dist'), }, }, output: { publicPath: 'auto', }, module: { rules: [ { test: /\.(js|jsx)$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-react', '@babel/preset-env'], }, }, }, ], }, plugins: [ new ModuleFederationPlugin({ name: 'host', remotes: { remote: 'remote@http://localhost:3001/remoteEntry.js', }, shared: { react: { singleton: true, eager: true }, 'react-dom': { singleton: true, eager: true }, }, }), new HtmlWebpackPlugin({ template: './public/index.html', }), ], resolve: { extensions: ['.js', '.jsx'], }, }; ```κΈ°λ³Έμ μΈ HTML ꡬ쑰λ₯Ό κ°μ§ `public/index.html`μ μμ±ν©λλ€(μ격 μ±κ³Ό μ μ¬). μ€μν κ²μ `
`μ λλ€.4. Babel μ€μΉ
`host`μ `remote` λλ ν°λ¦¬ μμͺ½ λͺ¨λμμ Babel μ’ μμ±μ μ€μΉν©λλ€:
```bash npm install --save-dev @babel/core @babel/preset-env @babel/preset-react babel-loader ```5. μ ν리μΌμ΄μ μ€ν
`host`μ `remote` λλ ν°λ¦¬ μμͺ½ λͺ¨λμμ `package.json`μ λ€μ μ€ν¬λ¦½νΈλ₯Ό μΆκ°ν©λλ€:
```json "scripts": { "start": "webpack serve" } ```μ΄μ λ μ ν리μΌμ΄μ μ λͺ¨λ μμν©λλ€:
```bash cd remote npm start cd ../host npm start ```λΈλΌμ°μ λ₯Ό μ΄κ³ `http://localhost:3000`μΌλ‘ μ΄λν©λλ€. νΈμ€νΈ μ ν리μΌμ΄μ λ΄μ μ격 μ»΄ν¬λνΈκ° λ λλ§λ κ²μ λ³Ό μ μμ΅λλ€.
μ£Όμ κ΅¬μ± μ΅μ μ€λͺ :
- `name`: μ ν리μΌμ΄μ μ κ³ μ ν μ΄λ¦μ λλ€.
- `filename`: λ ΈμΆλ λͺ¨λμ λν λ©νλ°μ΄ν°λ₯Ό ν¬ν¨ν νμΌμ μ΄λ¦μ λλ€(μ: `remoteEntry.js`).
- `exposes`: λ ΈμΆν λͺ¨λμ μ§μ νλ λͺ¨λ μ΄λ¦κ³Ό νμΌ κ²½λ‘μ λ§΅μ λλ€.
- `remotes`: κ° μ격 μ ν리μΌμ΄μ μ remoteEntry.js νμΌμ μ°Ύμ μμΉλ₯Ό μ§μ νλ μ격 μ ν리μΌμ΄μ μ΄λ¦κ³Ό URLμ λ§΅μ λλ€.
- `shared`: νΈμ€νΈμ μ격 μ ν리μΌμ΄μ κ°μ 곡μ λμ΄μΌ ν λͺ¨λ λͺ©λ‘μ λλ€. `singleton: true` μ΅μ μ κ° κ³΅μ λͺ¨λμ λ¨μΌ μΈμ€ν΄μ€λ§ λ‘λλλλ‘ λ³΄μ₯ν©λλ€. `eager: true` μ΅μ μ 곡μ λͺ¨λμ΄ μ¦μ(μ¦, λ€λ₯Έ λͺ¨λλ³΄λ€ λ¨Όμ ) λ‘λλλλ‘ λ³΄μ₯ν©λλ€.
κ³ κΈ λͺ¨λ νλλ μ΄μ κΈ°μ
λͺ¨λ νλλ μ΄μ μ ν¨μ¬ λ μ κ΅ν λ§μ΄ν¬λ‘ νλ‘ νΈμλ μν€ν μ²λ₯Ό ꡬμΆνλ λ° λμμ΄ λλ λ§μ κ³ κΈ κΈ°λ₯μ μ 곡ν©λλ€.
λμ μ격(Dynamic Remotes)
Webpack ꡬμ±μ μ격 μ ν리μΌμ΄μ μ URLμ νλμ½λ©νλ λμ λ°νμμ λμ μΌλ‘ λ‘λν μ μμ΅λλ€. μ΄λ₯Ό ν΅ν΄ νΈμ€νΈ μ ν리μΌμ΄μ μ λ€μ λΉλνμ§ μκ³ λ μ격 μ ν리μΌμ΄μ μ μμΉλ₯Ό μ½κ² μ λ°μ΄νΈν μ μμ΅λλ€.
μλ₯Ό λ€μ΄, μ격 μ ν리μΌμ΄μ μ URLμ κ΅¬μ± νμΌμ΄λ λ°μ΄ν°λ² μ΄μ€μ μ μ₯νκ³ JavaScriptλ₯Ό μ¬μ©νμ¬ λμ μΌλ‘ λ‘λν μ μμ΅λλ€.
```javascript // webpack.config.js νμΌμμ remotes: { remote: `promise new Promise(resolve => { const urlParams = new URLSearchParams(window.location.search); const remoteUrl = urlParams.get('remote'); // remoteUrlμ΄ 'http://localhost:3001/remoteEntry.js'μ κ°λ€κ³ κ°μ ν©λλ€ const script = document.createElement('script'); script.src = remoteUrl; script.onload = () => { // λͺ¨λ νλλ μ΄μ μ ν΅μ¬μ μ격 μ±μ΄ // μ격 μ±μ μ§μ λ μ΄λ¦μΌλ‘ μ¬μ© κ°λ₯νλ€λ κ²μ λλ€ resolve(window.remote); }; document.head.appendChild(script); })`, }, ```μ΄μ `?remote=http://localhost:3001/remoteEntry.js` 쿼리 λ§€κ°λ³μλ₯Ό μ¬μ©νμ¬ νΈμ€νΈ μ±μ λ‘λν μ μμ΅λλ€.
λ²μ κ΄λ¦¬λλ 곡μ λͺ¨λ
λͺ¨λ νλλ μ΄μ μ κ° λͺ¨λμ νΈν κ°λ₯ν λ²μ νλλ§ λ‘λλλλ‘ κ³΅μ λͺ¨λμ λ²μ κ΄λ¦¬ λ° μ€λ³΅ μ κ±°λ₯Ό μλμΌλ‘ μ²λ¦¬ν μ μμ΅λλ€. μ΄κ²μ λ§μ μ’ μμ±μ κ°μ§ ν¬κ³ 볡μ‘ν μ ν리μΌμ΄μ μ λ€λ£° λ νΉν μ€μν©λλ€.
Webpack ꡬμ±μμ κ° κ³΅μ λͺ¨λμ λ²μ λ²μλ₯Ό μ§μ ν μ μμ΅λλ€.
```javascript // webpack.config.js νμΌμμ shared: { react: { singleton: true, eager: true, requiredVersion: '^18.0.0' }, 'react-dom': { singleton: true, eager: true, requiredVersion: '^18.0.0' }, }, ```μ¬μ©μ μ μ λͺ¨λ λ‘λ
λͺ¨λ νλλ μ΄μ μ μ¬μ©νλ©΄ λ€λ₯Έ μμ€λ λ€λ₯Έ νμμμ λͺ¨λμ λ‘λνλ λ° μ¬μ©ν μ μλ μ¬μ©μ μ μ λͺ¨λ λ‘λλ₯Ό μ μν μ μμ΅λλ€. μ΄λ CDNμ΄λ μ¬μ©μ μ μ λͺ¨λ λ μ§μ€νΈλ¦¬μμ λͺ¨λμ λ‘λνλ λ° μ μ©ν μ μμ΅λλ€.
λ§μ΄ν¬λ‘ νλ‘ νΈμλ κ° μν 곡μ
λ§μ΄ν¬λ‘ νλ‘ νΈμλ μν€ν μ²μ μ΄λ €μ μ€ νλλ μλ‘ λ€λ₯Έ λ§μ΄ν¬λ‘ νλ‘ νΈμλ κ°μ μνλ₯Ό 곡μ νλ κ²μ λλ€. μ΄ λ¬Έμ λ₯Ό ν΄κ²°νκΈ° μν΄ λ€μκ³Ό κ°μ μ¬λ¬ μ κ·Ό λ°©μμ μ·¨ν μ μμ΅λλ€:
- URL κΈ°λ° μν κ΄λ¦¬: μνλ₯Ό URLμ μ μ₯νκ³ URLμ μ¬μ©νμ¬ λ§μ΄ν¬λ‘ νλ‘ νΈμλ κ°μ ν΅μ ν©λλ€. μ΄κ²μ κ°λ¨νκ³ μ§κ΄μ μΈ μ κ·Ό λ°©μμ΄μ§λ§ 볡μ‘ν μνμ κ²½μ° λ²κ±°λ‘μμ§ μ μμ΅λλ€.
- μ¬μ©μ μ μ μ΄λ²€νΈ(Custom events): μ¬μ©μ μ μ μ΄λ²€νΈλ₯Ό μ¬μ©νμ¬ λ§μ΄ν¬λ‘ νλ‘ νΈμλ κ°μ μν λ³κ²½μ λΈλ‘λμΊμ€νΈν©λλ€. μ΄λ λ§μ΄ν¬λ‘ νλ‘ νΈμλ κ°μ λμ¨ν κ²°ν©μ κ°λ₯νκ² νμ§λ§ μ΄λ²€νΈ ꡬλ μ κ΄λ¦¬νκΈ° μ΄λ €μΈ μ μμ΅λλ€.
- 곡μ μν κ΄λ¦¬ λΌμ΄λΈλ¬λ¦¬: Reduxλ MobXμ κ°μ 곡μ μν κ΄λ¦¬ λΌμ΄λΈλ¬λ¦¬λ₯Ό μ¬μ©νμ¬ μ 체 μ ν리μΌμ΄μ μ μνλ₯Ό κ΄λ¦¬ν©λλ€. μ΄λ μνλ₯Ό κ΄λ¦¬νλ μ€μ μ§μ€μ μ΄κ³ μΌκ΄λ λ°©λ²μ μ 곡νμ§λ§ νΉμ μν κ΄λ¦¬ λΌμ΄λΈλ¬λ¦¬μ λν μ’ μμ±μ μ λ°ν μ μμ΅λλ€.
- λ©μμ§ λΈλ‘컀(Message Broker): RabbitMQλ Kafkaμ κ°μ λ©μμ§ λΈλ‘컀λ₯Ό μ¬μ©νμ¬ λ§μ΄ν¬λ‘ νλ‘ νΈμλ κ°μ ν΅μ λ° μν 곡μ λ₯Ό μ©μ΄νκ² ν©λλ€. μ΄κ²μ λ 볡μ‘ν μ루μ μ΄μ§λ§ λμ μμ€μ μ μ°μ±κ³Ό νμ₯μ±μ μ 곡ν©λλ€.
λͺ¨λ νλλ μ΄μ μΌλ‘ λ§μ΄ν¬λ‘ νλ‘ νΈμλλ₯Ό ꡬννκΈ° μν λͺ¨λ² μ¬λ‘
λͺ¨λ νλλ μ΄μ μΌλ‘ λ§μ΄ν¬λ‘ νλ‘ νΈμλλ₯Ό ꡬνν λ μΌλμ λμ΄μΌ ν λͺ κ°μ§ λͺ¨λ² μ¬λ‘λ λ€μκ³Ό κ°μ΅λλ€:
- κ° λ§μ΄ν¬λ‘ νλ‘ νΈμλμ λν λͺ νν κ²½κ³ μ μ: κ° λ§μ΄ν¬λ‘ νλ‘ νΈμλλ νΉμ λΉμ¦λμ€ λλ©μΈμ΄λ κΈ°λ₯μ μ± μμ ΈμΌ νλ©° μ μ μλ μΈν°νμ΄μ€λ₯Ό κ°μ ΈμΌ ν©λλ€.
- μΌκ΄λ κΈ°μ μ€ν μ¬μ©: λͺ¨λ νλλ μ΄μ μ μλ‘ λ€λ₯Έ λ§μ΄ν¬λ‘ νλ‘ νΈμλμ λν΄ λ€λ₯Έ κΈ°μ μ μ¬μ©ν μ μκ² νμ§λ§, 볡μ‘μ±μ μ€μ΄κ³ μ μ§λ³΄μμ±μ ν₯μμν€κΈ° μν΄ μΌλ°μ μΌλ‘ μΌκ΄λ κΈ°μ μ€νμ μ¬μ©νλ κ²μ΄ μ’μ΅λλ€.
- λͺ νν ν΅μ νλ‘ν μ½ μ€μ : λ§μ΄ν¬λ‘ νλ‘ νΈμλκ° μλ‘ μνΈ μμ©νλ λ°©μμ λν λͺ νν ν΅μ νλ‘ν μ½μ μ μν©λλ€.
- λ°°ν¬ νλ‘μΈμ€ μλν: λ§μ΄ν¬λ‘ νλ‘ νΈμλκ° λ 립μ μ΄κ³ μμ μ μΌλ‘ λ°°ν¬λ μ μλλ‘ λ°°ν¬ νλ‘μΈμ€λ₯Ό μλνν©λλ€. CI/CD νμ΄νλΌμΈκ³Ό μ½λν μΈνλΌ(Infrastructure-as-code) λꡬ μ¬μ©μ κ³ λ €νμΈμ.
- λ§μ΄ν¬λ‘ νλ‘ νΈμλ μ±λ₯ λͺ¨λν°λ§: μ±λ₯ λ³λͺ© νμμ μλ³νκ³ ν΄κ²°νκΈ° μν΄ λ§μ΄ν¬λ‘ νλ‘ νΈμλμ μ±λ₯μ λͺ¨λν°λ§ν©λλ€. Google Analytics, New Relic λλ Datadogκ³Ό κ°μ λꡬλ₯Ό μ¬μ©νμΈμ.
- κ²¬κ³ ν μ€λ₯ μ²λ¦¬ ꡬν: μ ν리μΌμ΄μ μ΄ μ₯μ μ νλ ₯μ μΌλ‘ λμ²ν μ μλλ‘ κ²¬κ³ ν μ€λ₯ μ²λ¦¬λ₯Ό ꡬνν©λλ€.
- λΆμ°λ κ±°λ²λμ€ λͺ¨λΈ μ±ν: μ λ°μ μΈ μΌκ΄μ±κ³Ό νμ§μ μ μ§νλ©΄μ νμ΄ μμ μ λ§μ΄ν¬λ‘ νλ‘ νΈμλμ λν κ²°μ μ λ΄λ¦΄ μ μλλ‘ κΆνμ λΆμ¬ν©λλ€.
μ€μ μΈκ³μμμ λͺ¨λ νλλ μ΄μ μ μ© μ¬λ‘
ꡬ체μ μΈ μ¬λ‘ μ°κ΅¬λ μ’ μ’ κΈ°λ°μ΄μ§λ§, λͺ¨λ νλλ μ΄μ μ΄ λ§€μ° μ μ©ν μ μλ λͺ κ°μ§ μΌλ°μ μΈ μλ리μ€λ λ€μκ³Ό κ°μ΅λλ€:
- μ μμκ±°λ νλ«νΌ: μμ μΈκΈνλ―μ΄, λκ·λͺ¨ μ μμκ±°λ νλ«νΌμ λͺ¨λ νλλ μ΄μ μ μ¬μ©νμ¬ μ ν μΉ΄νλ‘κ·Έ, μΌν μΉ΄νΈ, κ²°μ νλ‘μΈμ€ λ° μ¬μ©μ κ³μ κ΄λ¦¬λ₯Ό μν λ 립μ μΈ λ§μ΄ν¬λ‘ νλ‘ νΈμλλ₯Ό ꡬμΆν μ μμ΅λλ€. μ΄λ₯Ό ν΅ν΄ μ¬λ¬ νμ΄ μ΄λ¬ν κΈ°λ₯μ λ 립μ μΌλ‘ μμ νκ³ μ ν리μΌμ΄μ μ λ€λ₯Έ λΆλΆμ μν₯μ μ£Όμ§ μκ³ λ°°ν¬ν μ μμ΅λλ€. κΈλ‘λ² νλ«νΌμ μ격 λͺ¨λμ ν΅ν΄ λ€λ₯Έ μ§μμ λν κΈ°λ₯μ λ§μΆ€νν μ μμ΅λλ€.
- κΈμ΅ μλΉμ€ μ ν리μΌμ΄μ : κΈμ΅ μλΉμ€ μ ν리μΌμ΄μ μ μ’ μ’ λ€μν κΈ°λ₯μ κ°μ§ 볡μ‘ν μ¬μ©μ μΈν°νμ΄μ€λ₯Ό κ°μ§λλ€. λͺ¨λ νλλ μ΄μ μ μ¬μ©νμ¬ λ€μν κ³μ μ ν, κ±°λ νλ«νΌ λ° λ³΄κ³ λμ보λλ₯Ό μν λ 립μ μΈ λ§μ΄ν¬λ‘ νλ‘ νΈμλλ₯Ό ꡬμΆν μ μμ΅λλ€. νΉμ κ΅κ°μ κ³ μ ν κ·μ μ€μ κΈ°λ₯μ λͺ¨λ νλλ μ΄μ μ ν΅ν΄ μ 곡λ μ μμ΅λλ€.
- ν¬μ€μΌμ΄ ν¬νΈ: ν¬μ€μΌμ΄ ν¬νΈμ λͺ¨λ νλλ μ΄μ μ μ¬μ©νμ¬ νμ κ΄λ¦¬, μμ½ μ€μΌμ€λ§ λ° μλ£ κΈ°λ‘ μ κ·Όμ μν λ 립μ μΈ λ§μ΄ν¬λ‘ νλ‘ νΈμλλ₯Ό ꡬμΆν μ μμ΅λλ€. λ€λ₯Έ 보νμ¬λ μ§μμ μν λ€λ₯Έ λͺ¨λμ΄ λμ μΌλ‘ λ‘λλ μ μμ΅λλ€.
- μ½ν μΈ κ΄λ¦¬ μμ€ν (CMS): CMSλ λͺ¨λ νλλ μ΄μ μ μ¬μ©νμ¬ μ¬μ©μκ° νμ¬ κ°λ°μμ μ격 λͺ¨λμ λ‘λνμ¬ μΉμ¬μ΄νΈμ μ¬μ©μ μ μ κΈ°λ₯μ μΆκ°ν μ μλλ‘ ν μ μμ΅λλ€. λ€μν ν λ§, νλ¬κ·ΈμΈ λ° μμ ―μ΄ λ 립μ μΈ λ§μ΄ν¬λ‘ νλ‘ νΈμλλ‘ λ°°ν¬λ μ μμ΅λλ€.
- νμ΅ κ΄λ¦¬ μμ€ν (LMS): LMSλ λ 립μ μΌλ‘ κ°λ°λ κ³Όμ μ λͺ¨λ νλλ μ΄μ μ ν΅ν΄ ν΅ν©λ νλ«νΌμΌλ‘ μ 곡ν μ μμ΅λλ€. κ°λ³ κ³Όμ μ λν μ λ°μ΄νΈλ νλ«νΌ μ 체μ μ¬λ°°ν¬λ₯Ό νμλ‘ νμ§ μμ΅λλ€.
κ²°λ‘
Webpack 5μ JavaScript λͺ¨λ νλλ μ΄μ μ λ§μ΄ν¬λ‘ νλ‘ νΈμλ μν€ν μ²λ₯Ό ꡬμΆνλ κ°λ ₯νκ³ μ μ°ν λ°©λ²μ μ 곡ν©λλ€. μ΄λ₯Ό ν΅ν΄ λ³λλ‘ μ»΄νμΌλ JavaScript μ ν리μΌμ΄μ κ°μ λ°νμμ μ½λλ₯Ό 곡μ νμ¬ λ 립μ μΈ λ°°ν¬, κΈ°μ λ€μμ± λ° ν₯μλ ν μμ¨μ±μ κ°λ₯νκ² ν©λλ€. μ΄ κ°μ΄λμμ μ€λͺ ν λͺ¨λ² μ¬λ‘λ₯Ό λ°λ₯΄λ©΄ λͺ¨λ νλλ μ΄μ μ νμ©νμ¬ νμ₯ κ°λ₯νκ³ μ μ§λ³΄μ μ©μ΄νλ©° νμ μ μΈ μΉ μ ν리μΌμ΄μ μ ꡬμΆν μ μμ΅λλ€.
νλ‘ νΈμλ κ°λ°μ λ―Έλλ μμ¬ν μ¬μ§ μμ΄ λͺ¨λμ λ° λΆμ° μν€ν μ²λ‘ κΈ°μΈκ³ μμ΅λλ€. λͺ¨λ νλλ μ΄μ μ μ΄λ¬ν νλμ μΈ μμ€ν μ ꡬμΆνκΈ° μν μ€μν λꡬλ₯Ό μ 곡νμ¬ νμ΄ λ λΉ λ₯Έ μλ, μ μ°μ± λ° λ³΅μλ ₯μ κ°μΆ 볡μ‘ν μ ν리μΌμ΄μ μ λ§λ€ μ μλλ‘ ν©λλ€. κΈ°μ μ΄ μ±μν΄μ§μ λ°λΌ ν¨μ¬ λ νμ μ μΈ μ¬μ© μ¬λ‘μ λͺ¨λ² μ¬λ‘κ° λ±μ₯ν κ²μΌλ‘ κΈ°λν μ μμ΅λλ€.